ReadStream பொருள்
ஒரு ReadStream என்பது ஒரு வளத்திலிருந்து தரவைப் படிக்க உங்களை அனுமதிக்கும் ஒரு ஸ்ட்ரீம் ஆகும். Node.js வெவ்வேறு பயன்பாட்டு நோக்கங்களுக்கான ReadStream செயலாக்கங்களை வழங்குகிறது, கோப்புகளிலிருந்து வாசிப்பதற்கு (fs.ReadStream) அல்லது நிலையான உள்ளீட்டிலிருந்து (process.stdin) போன்றவை.
ReadStreams stream.Readable இடைமுகத்தை செயல்படுத்துகின்றன, அதாவது அவை அசிங்க்ரோனஸாக தரவைப் படிக்கவும், backpressure ஐ கையாளவும் மற்றும் வெவ்வேறு ஸ்ட்ரீம் பயன்முறைகளுடன் (flowing/paused) பணிபுரியவும் முறைகள் மற்றும் நிகழ்வுகளை வழங்குகின்றன.
fs.ReadStream
கோப்புகளிலிருந்து வாசிப்பதற்கு
process.stdin
நிலையான உள்ளீட்டிலிருந்து வாசிப்பதற்கு
net.Socket
நெட்வொர்க் இணைப்புகளிலிருந்து வாசிப்பதற்கு
பொதுவான ReadStream வகைகள்
| வகை | விளக்கம் |
|---|---|
| fs.ReadStream | கோப்புகளிலிருந்து வாசிப்பதற்கு |
| process.stdin | நிலையான உள்ளீட்டிலிருந்து வாசிப்பதற்கு |
| net.Socket | நெட்வொர்க் இணைப்புகளிலிருந்து வாசிப்பதற்கு |
| http.IncomingMessage | HTTP கோரிக்கை உடல்களை வாசிப்பதற்கு |
ReadStream பண்புகள்
Node.js ReadStream பொருள்களில் பொதுவாகக் கிடைக்கும் பண்புகள் இங்கே உள்ளன, முதன்மையாக fs.ReadStream செயலாக்கத்தை அடிப்படையாகக் கொண்டவை:
| பண்பு | விளக்கம் |
|---|---|
| readStream.bytesRead | இதுவரை வாசிக்கப்பட்ட பைட்டுகளின் எண்ணிக்கை |
| readStream.path | இந்த ReadStream வாசிக்கும் கோப்பு பாதை (fs.ReadStream மட்டும்) |
| readStream.pending | true எனில், அடிப்படை கோப்பு இன்னும் திறக்கப்படவில்லை |
| readStream.readableHighWaterMark | இந்த ReadStream க்கான highWaterMark மதிப்பைத் தரும் |
| readStream.readableLength | வாசிக்கத் தயாராக read queue இல் உள்ள பைட்டுகள் (அல்லது பொருள்கள்) எண்ணிக்கையைத் தரும் |
| readStream.readableEnded | 'end' நிகழ்வு வெளியிடப்படும் போது true ஆக மாறும் |
| readStream.readableFlowing | ReadStream இன் நிலையைக் குறிக்கிறது (null, false, அல்லது true) |
| readStream.destroyed | ஸ்ட்ரீம் அழிக்கப்பட்டதா என்பதைக் குறிக்கிறது |
ReadStream முறைகள்
ReadStream பொருள்களில் கிடைக்கும் மிக முக்கியமான முறைகள் இங்கே உள்ளன:
| முறை | விளக்கம் |
|---|---|
| readStream.read([size]) | உள் buffer இலிருந்து தரவைப் படித்து தரும். தரவு கிடைக்கவில்லை என்றால், null திரும்பும். size குறிப்பிடப்பட்டால், அந்த எண்ணிக்கையிலான பைட்டுகளைப் படிக்க முயற்சிக்கிறது |
| readStream.pause() | தரவு வாசிப்பை இடைநிறுத்துகிறது, ஸ்ட்ரீமை flowing பயன்முறையிலிருந்து வெளியேற்றுகிறது |
| readStream.resume() | pause() அழைப்புக்குப் பிறகு வாசிப்பைத் தொடர்கிறது, ஸ்ட்ரீமை flowing பயன்முறைக்கு மாற்றுகிறது |
| readStream.pipe(destination[, options]) | ஒரு Writable ஸ்ட்ரீமை ReadStream உடன் இணைக்கிறது, destination ஒரு வேகமான ReadStream மூலம் மூழ்கடிக்கப்படாமல் இருக்கும் வகையில் ஓட்டத்தை தானாகவே நிர்வகிக்கிறது |
| readStream.unpipe([destination]) | pipe() பயன்படுத்தி முன்பு இணைக்கப்பட்ட Writable ஸ்ட்ரீமைத் துண்டிக்கிறது |
| readStream.unshift(chunk[, encoding]) | தரவின் ஒரு chunk ஐ உள் buffer க்கு மீண்டும் தள்ளுகிறது, அது அடுத்த read() அழைப்பால் திரும்பப் பெறப்படும் |
| readStream.wrap(stream) | பழைய பாணியின் readable ஸ்ட்ரீமை புதிய பாணியின் readable ஸ்ட்ரீமாக மூடுகிறது |
| readStream.destroy([error]) | ஸ்ட்ரீமை அழிக்கிறது, மற்றும் விருப்பமாக error நிகழ்வை வெளியிடுகிறது. இந்த அழைப்புக்குப் பிறகு, ReadStream பயன்படுத்த முடியாது |
| readStream.setEncoding(encoding) | ஸ்ட்ரீமிலிருந்து வாசிக்கப்பட்ட தரவுக்கான எழுத்து encoding ஐ அமைக்கிறது. அமைக்கப்பட்டால், ஸ்ட்ரீம் தரவை Buffer பொருள்களுக்குப் பதிலாக சரங்களாக decode செய்யும் |
ReadStream நிகழ்வுகள்
ReadStream பொருள்கள் பின்வரும் நிகழ்வுகளை வெளியிடுகின்றன:
| நிகழ்வு | விளக்கம் |
|---|---|
| 'close' | ஸ்ட்ரீம் மற்றும் அதன் அடிப்படை வளங்கள் ஏதேனும் மூடப்படும் போது வெளியிடப்படுகிறது |
| 'data' | ஸ்ட்ரீமிலிருந்து தரவு வாசிக்கக் கிடைக்கும் போது வெளியிடப்படுகிறது. தரவு ஒரு Buffer அல்லது string ஆக இருக்கும், setEncoding() உடன் அமைக்கப்பட்ட encoding ஐப் பொறுத்து |
| 'end' | ஸ்ட்ரீமிலிருந்து உட்கொள்ள இன்னும் தரவு இல்லாதபோது வெளியிடப்படுகிறது |
| 'error' | வாசிப்பின் போது பிழை ஏற்பட்டால் வெளியிடப்படுகிறது. இந்த நிகழ்வுக்குப் பிறகு ஸ்ட்ரீம் மூடப்படும் |
| 'open' | அடிப்படை வளம் (எ.க., கோப்பு descriptor) திறக்கப்படும் போது வெளியிடப்படுகிறது (fs.ReadStream க்கு குறிப்பிட்டது) |
| 'readable' | ஸ்ட்ரீமிலிருந்து தரவு வாசிக்கக் கிடைக்கும் போது அல்லது ஸ்ட்ரீமின் முடிவு அடையப்படும் போது வெளியிடப்படுகிறது |
| 'ready' | ஸ்ட்ரீம் பயன்படுத்த தயாராக இருக்கும் போது வெளியிடப்படுகிறது |
| 'pause' | ஸ்ட்ரீம் இடைநிறுத்தப்படும் போது வெளியிடப்படுகிறது |
| 'resume' | ஸ்ட்ரீம் மீண்டும் தொடங்கப்படும் போது வெளியிடப்படுகிறது |
ஒரு கோப்பிலிருந்து வாசித்தல்
இந்த எடுத்துக்காட்டு ஒரு கோப்பு ReadStream ஐ உருவாக்குவதும் அதிலிருந்து தரவை வாசிப்பதும் எப்படி என்பதைக் காட்டுகிறது:
const fs = require('fs');
const path = require('path');
// எடுத்துக்காட்டுக்கு ஒரு மாதிரி கோப்பை உருவாக்கு
const sampleFile = path.join(__dirname, 'readstream-example.txt');
fs.writeFileSync(sampleFile, 'This is a test file.\nIt has multiple lines.\nEach line has its own content.\nStreaming makes file reading efficient.');
// கோப்பிலிருந்து வாசிக்க ஒரு ReadStream உருவாக்க
const readStream = fs.createReadStream(sampleFile, {
// விருப்பங்கள்
encoding: 'utf8', // encoding ஐ அமை (utf8, ascii, binary, முதலியன)
highWaterMark: 64, // பைட்டுகளில் Buffer அளவு
autoClose: true // ஸ்ட்ரீம் முடிவடையும் போது தானாகவே கோப்பு descriptor ஐ மூடு
});
console.log('File ReadStream properties:');
console.log(`- Path: ${readStream.path}`);
console.log(`- Pending: ${readStream.pending}`);
console.log(`- High Water Mark: ${readStream.readableHighWaterMark} bytes`);
// ஸ்ட்ரீம் நிகழ்வுகளைக் கையாள
readStream.on('open', (fd) => {
console.log(`File opened with descriptor: ${fd}`);
});
readStream.on('ready', () => {
console.log('ReadStream is ready');
});
// தரவு நிகழ்வுகளைக் கையாள
readStream.on('data', (chunk) => {
console.log('\nReceived chunk:');
console.log('-'.repeat(20));
console.log(chunk);
console.log('-'.repeat(20));
console.log(`Bytes read so far: ${readStream.bytesRead}`);
});
readStream.on('end', () => {
console.log('\nReached end of file');
console.log(`Total bytes read: ${readStream.bytesRead}`);
// மாதிரி கோப்பை சுத்தம் செய்
fs.unlinkSync(sampleFile);
console.log('Sample file removed');
});
readStream.on('close', () => {
console.log('Stream closed');
});
readStream.on('error', (err) => {
console.error(`Error: ${err.message}`);
});
ஸ்ட்ரீம் ஓட்டத்தைக் கட்டுப்படுத்துதல்
இந்த எடுத்துக்காட்டு pause() மற்றும் resume() உடன் தரவின் ஓட்டத்தைக் கட்டுப்படுத்துவது எப்படி என்பதை நிரூபிக்கிறது:
const fs = require('fs');
const path = require('path');
// ஓட்டக் கட்டுப்பாட்டு எடுத்துக்காட்டுக்கு ஒரு பெரிய மாதிரி கோப்பை உருவாக்கு
const flowFile = path.join(__dirname, 'flow-control-example.txt');
let sampleContent = '';
for (let i = 1; i <= 1000; i++) {
sampleContent += `This is line ${i} of the test file.\n`;
}
fs.writeFileSync(flowFile, sampleContent);
// ஒரு ReadStream உருவாக்க
const readStream = fs.createReadStream(flowFile, {
encoding: 'utf8',
highWaterMark: 1024 // 1KB buffer
});
let chunkCount = 0;
let totalBytes = 0;
let isPaused = false;
// ஓட்டக் கட்டுப்பாட்டுடன் தரவு chunks களைக் கையாள
readStream.on('data', (chunk) => {
chunkCount++;
totalBytes += chunk.length;
console.log(`Chunk #${chunkCount} received, size: ${chunk.length} bytes`);
// ஓட்டக் கட்டுப்பாட்டை நிரூபிக்க ஒவ்வொரு 5 chunks க்கும் ஸ்ட்ரீமை இடைநிறுத்து
if (chunkCount % 5 === 0 && !isPaused) {
console.log('\nPausing the stream for 1 second...');
isPaused = true;
// ஸ்ட்ரீமை இடைநிறுத்து
readStream.pause();
// 1 விநாடிக்குப் பிறகு மீண்டும் தொடங்கு
setTimeout(() => {
console.log('Resuming the stream...\n');
isPaused = false;
readStream.resume();
}, 1000);
}
});
readStream.on('end', () => {
console.log(`\nFinished reading file. Received ${chunkCount} chunks, ${totalBytes} bytes total.`);
// மாதிரி கோப்பை சுத்தம் செய்
fs.unlinkSync(flowFile);
console.log('Sample file removed');
});
readStream.on('error', (err) => {
console.error(`Error: ${err.message}`);
});
read() முறையைப் பயன்படுத்துதல்
இந்த எடுத்துக்காட்டு 'readable' நிகழ்வில் read() முறையைப் பயன்படுத்துவதை நிரூபிக்கிறது:
const fs = require('fs');
const path = require('path');
// ஒரு மாதிரி கோப்பை உருவாக்கு
const readableFile = path.join(__dirname, 'readable-example.txt');
fs.writeFileSync(readableFile, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.repeat(100));
// auto-flowing இல்லாமல் ஒரு ReadStream உருவாக்கு
const readStream = fs.createReadStream(readableFile, {
highWaterMark: 32 // பல வாசிப்புகளை நிரூபிக்க சிறிய buffer
});
console.log('Using the readable event and read() method:');
// கைமுறை வாசிப்புக்கு 'readable' நிகழ்வைப் பயன்படுத்துதல்
readStream.on('readable', () => {
let chunk;
// வாசிக்க இன்னும் தரவு இல்லாதபோது read() null திரும்பும்
while (null !== (chunk = readStream.read(16))) {
console.log(`Read ${chunk.length} bytes: ${chunk.toString('utf8').substring(0, 10)}...`);
}
});
readStream.on('end', () => {
console.log('End of stream reached');
// மாதிரி கோப்பை சுத்தம் செய்
fs.unlinkSync(readableFile);
console.log('Sample file removed');
});
readStream.on('error', (err) => {
console.error(`Error: ${err.message}`);
});
ஸ்ட்ரீம்களுக்கு இடையே Piping செய்தல்
இந்த எடுத்துக்காட்டு pipe() ஐப் பயன்படுத்தி ஒரு ReadStream இலிருந்து ஒரு WriteStream க்கு தரவை அனுப்புவது எப்படி என்பதை நிரூபிக்கிறது:
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');
// மூல மற்றும் இலக்கு கோப்பு பாதைகள்
const sourceFile = path.join(__dirname, 'pipe-source-example.txt');
const destFile = path.join(__dirname, 'pipe-destination.txt');
const compressedFile = path.join(__dirname, 'pipe-compressed.gz');
// மாதிரி உள்ளடக்கத்தை உருவாக்கு
fs.writeFileSync(sourceFile, 'This is the source content for the pipe example.\n'.repeat(100));
// ReadStream மற்றும் பல்வேறு WriteStreams உருவாக்கு
const readStream = fs.createReadStream(sourceFile);
const writeStream = fs.createWriteStream(destFile);
const compressStream = zlib.createGzip(); // சுருக்கம் transform ஸ்ட்ரீம்
const compressedWriteStream = fs.createWriteStream(compressedFile);
// ReadStream ஐ நேரடியாக WriteStream க்கு pipe செய்
readStream.pipe(writeStream);
// நிறைவு நிகழ்வுகளைக் கேள்
writeStream.on('finish', () => {
console.log(`File copied from ${sourceFile} to ${destFile}`);
// தொடர்ச்சியான pipes ஐ நிரூபிக்க ஒரு புதிய ReadStream உருவாக்கு
const readStream2 = fs.createReadStream(sourceFile);
// பல pipes ஐ தொடர்ச்சியாக இணை: read -> compress -> write
readStream2.pipe(compressStream).pipe(compressedWriteStream);
compressedWriteStream.on('finish', () => {
console.log(`File compressed from ${sourceFile} to ${compressedFile}`);
// கோப்பு அளவுகளை ஒப்பிடு
const originalSize = fs.statSync(sourceFile).size;
const compressedSize = fs.statSync(compressedFile).size;
console.log(`Original size: ${originalSize} bytes`);
console.log(`Compressed size: ${compressedSize} bytes`);
console.log(`Compression ratio: ${(compressedSize / originalSize * 100).toFixed(2)}%`);
// நிரூபணத்திற்குப் பிறகு கோப்புகளை சுத்தம் செய்
[sourceFile, destFile, compressedFile].forEach(file => {
fs.unlinkSync(file);
});
console.log('All sample files removed');
});
});
// பிழைகளைக் கையாள
readStream.on('error', (err) => console.error(`Read error: ${err.message}`));
writeStream.on('error', (err) => console.error(`Write error: ${err.message}`));
compressStream.on('error', (err) => console.error(`Compression error: ${err.message}`));
compressedWriteStream.on('error', (err) => console.error(`Compressed write error: ${err.message}`));
நிலையான உள்ளீட்டிலிருந்து வாசித்தல்
இந்த எடுத்துக்காட்டு process.stdin ReadStream ஐப் பயன்படுத்துவது எப்படி என்பதைக் காட்டுகிறது:
// process.stdin ஒரு ReadStream ஆகும்
console.log('Enter some text (press Ctrl+D or Ctrl+C to end input):');
// Buffer பொருள்களுக்குப் பதிலாக சரங்களைப் பெற utf8 க்கு encoding ஐ அமை
process.stdin.setEncoding('utf8');
let inputData = '';
// stdin இலிருந்து தரவைக் கையாள
process.stdin.on('data', (chunk) => {
console.log(`Received chunk: "${chunk.trim()}"`);
inputData += chunk;
});
// உள்ளீட்டின் முடிவைக் கையாள
process.stdin.on('end', () => {
console.log('\nEnd of input.');
console.log(`Total input received: ${inputData.length} characters`);
console.log('You entered:');
console.log('-'.repeat(20));
console.log(inputData);
console.log('-'.repeat(20));
});
// Ctrl+C (SIGINT) ஐக் கையாள
process.on('SIGINT', () => {
console.log('\nInput interrupted with Ctrl+C');
process.exit();
});
// குறிப்பு: இந்த எடுத்துக்காட்டுக்கு ஒரு முனையத்தில் பயனர் உள்ளீடு தேவை
// W3Schools TryIt எடிட்டரில் திறம்பட நிரூபிக்க முடியாது
HTTP ReadStream எடுத்துக்காட்டு
இந்த எடுத்துக்காட்டு HTTP கோரிக்கை தரவைக் கையாள ஒரு ReadStream ஐப் பயன்படுத்துவது எப்படி என்பதைக் காட்டுகிறது:
const http = require('http');
// ஒரு HTTP சேவையகத்தை உருவாக்கு
const server = http.createServer((req, res) => {
// req ஒரு http.IncomingMessage, இது ஒரு ReadStream ஆகும்
console.log(`Received ${req.method} request to ${req.url}`);
// பதில் தலைப்புகளை அமை
res.setHeader('Content-Type', 'text/plain');
// வெவ்வேறு வகையான கோரிக்கைகளைக் கையாள
if (req.method === 'GET') {
res.end('Send a POST request with a body to see the ReadStream in action');
}
else if (req.method === 'POST') {
// கோரிக்கை ஸ்ட்ரீமுக்கான encoding ஐ அமை
req.setEncoding('utf8');
let body = '';
// கோரிக்கை ஸ்ட்ரீமிலிருந்து தரவு நிகழ்வுகளைக் கையாள
req.on('data', (chunk) => {
console.log(`Received chunk of ${chunk.length} bytes`);
body += chunk;
// ஒரு எளிய flood பாதுகாப்பை செயல்படுத்து
if (body.length > 1e6) {
// உடல் மிகப் பெரியதாக இருந்தால், ஸ்ட்ரீமை அழி
body = '';
res.writeHead(413, {'Content-Type': 'text/plain'});
res.end('Request entity too large');
req.destroy();
}
});
// கோரிக்கை ஸ்ட்ரீமின் முடிவைக் கையாள
req.on('end', () => {
console.log('End of request data');
try {
// JSON ஆக parse செய்ய முயற்சி
const data = JSON.parse(body);
console.log('Parsed JSON data:', data);
// ஒரு பதிலை அனுப்பு
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(JSON.stringify({
message: 'Data received',
size: body.length,
data: data
}));
} catch (e) {
// செல்லுபடியாகும் JSON இல்லையென்றால், raw தரவை echo back செய்
console.log('Could not parse as JSON, treating as plain text');
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(`Received ${body.length} bytes of data:\n${body}`);
}
});
}
else {
// மற்ற HTTP முறைகளுக்கு
res.writeHead(405, {'Content-Type': 'text/plain'});
res.end('Method not allowed');
}
});
// சேவையகத்தைத் தொடங்கு
const PORT = 8080;
server.listen(PORT, () => {
console.log(`HTTP ReadStream example server running at http://localhost:${PORT}`);
console.log('To test:');
console.log(`1. Open http://localhost:${PORT} in a browser for GET request`);
console.log(`2. Use curl or Postman to send POST requests with a body to http://localhost:${PORT}`);
});
// குறிப்பு: curl உடன் சோதிக்க:
// curl -X POST -H "Content-Type: application/json" -d '{"name":"John","age":30}' http://localhost:8080
ReadStreams உடன் பிழை கையாளுதல்
இந்த எடுத்துக்காட்டு ReadStreams உடன் சரியான பிழை கையாளுதலை நிரூபிக்கிறது:
const fs = require('fs');
const path = require('path');
// சரியான பிழை கையாளுதலுடன் ஒரு ReadStream உருவாக்கி கையாளும் செயல்பாடு
function readWithErrorHandling(filePath) {
console.log(`Attempting to read: ${filePath}`);
// ReadStream ஐ உருவாக்கு
const readStream = fs.createReadStream(filePath);
// முடிவு அல்லது பிழையைப் பிடிக்க promise ஐ அமை
return new Promise((resolve, reject) => {
let data = '';
// தரவு நிகழ்வுகளைக் கையாள
readStream.on('data', (chunk) => {
data += chunk;
});
// வெற்றிகரமான நிறைவைக் கையாள
readStream.on('end', () => {
console.log(`Successfully read ${readStream.bytesRead} bytes from ${filePath}`);
resolve(data);
});
// பிழைகளைக் கையாள
readStream.on('error', (err) => {
console.error(`Error reading ${filePath}: ${err.message}`);
reject(err);
});
// ஸ்ட்ரீம் மூடல் (பிழை இருந்தாலும் எப்போதும் நடக்கும்)
readStream.on('close', () => {
console.log(`Stream for ${filePath} closed`);
});
});
}
// இரண்டும் இருக்கும் மற்றும் இல்லாத கோப்புகளுடன் சோதிக்க
const existingFile = path.join(__dirname, 'test-existing.txt');
const nonExistingFile = path.join(__dirname, 'non-existing-file.txt');
// சோதனை கோப்பை உருவாக்கு
fs.writeFileSync(existingFile, 'This is test content for error handling example');
// எடுத்துக்காட்டு 1: இருக்கும் கோப்பை வாசித்தல்
console.log('Example 1: Reading an existing file');
readWithErrorHandling(existingFile)
.then(data => {
console.log('File content:', data);
// எடுத்துக்காட்டு 2: இல்லாத கோப்பை வாசித்தல்
console.log('\nExample 2: Reading a non-existing file');
return readWithErrorHandling(nonExistingFile);
})
.catch(err => {
console.log('Error caught in Promise catch:', err.message);
})
.finally(() => {
// சோதனை கோப்பை சுத்தம் செய்
if (fs.existsSync(existingFile)) {
fs.unlinkSync(existingFile);
console.log('Test file removed');
}
});
// எடுத்துக்காட்டு 3: அழிக்கப்பட்ட ஸ்ட்ரீம்களை நிரூபித்தல்
console.log('\nExample 3: Demonstrating destroyed streams');
const destroyTestFile = path.join(__dirname, 'destroy-test.txt');
fs.writeFileSync(destroyTestFile, 'A'.repeat(10000));
const destroyStream = fs.createReadStream(destroyTestFile);
destroyStream.on('data', (chunk) => {
console.log(`Received ${chunk.length} bytes before destroying the stream`);
// முதல் chunk பெற்ற பிறகு ஸ்ட்ரீமை அழி
console.log('Deliberately destroying the stream');
destroyStream.destroy(new Error('Stream manually destroyed'));
});
destroyStream.on('error', (err) => {
console.error(`Destruction error: ${err.message}`);
});
destroyStream.on('close', () => {
console.log('Destroyed stream closed');
// சுத்தம் செய்
fs.unlinkSync(destroyTestFile);
console.log('Destroy test file removed');
});
ReadStreams க்கான சிறந்த நடைமுறைகள்
Node.js இல் ReadStreams உடன் பணிபுரியும் போது, இந்த சிறந்த நடைமுறைகளைக் கவனியுங்கள்: